package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.*;
import com.itheima.service.DeptService;
import com.itheima.service.EmpExprService;
import com.itheima.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {

    //注入Service层对象，因为继承的ServiceImpl有操作集合的方法，EmpService没有
    @Autowired
    private DeptService deptService;

    @Autowired
    private EmpExprService empExprService;

    /**
     * 分页查询
     *
     * @param param
     */
    @Override
    public PageResult<Emp> getPageResult(EmpQueryParam param) {

        //创建Page对象
        Page<Emp> page = new Page<>(param.getPage(), param.getPageSize());


        //根据修改时间倒序排序查询
        page.addOrder(OrderItem.desc("update_time"));
 /*
        //创建LambdaQuerWrapper对象
        LambdaUpdateWrapper<Emp> queryWrapper = new LambdaUpdateWrapper<>();


       //链式编程，用动态SQL语句进行条件查询
        queryWrapper.like(param.getName() != null && !param.getName().isEmpty(), Emp::getName, param.getName())
                .eq(param.getGender() != null ,Emp::getGender,param.getGender())
                .between(param.getBegin() != null && param.getEnd() != null,Emp::getEntryDate ,param.getBegin(),param.getEnd());

        //调用page方法完成分页查询
        page = page(page, queryWrapper);
        */

        //使用lambdaQuery方法构建查询条件,链式编程，用动态SQL语句进行条件查询(判断条件为空字符或者为null不会拼接，字段名-name,值-value)
         page = lambdaQuery().like(param.getName() != null && !param.getName().isEmpty(), Emp::getName, param.getName())
                .eq(param.getGender() != null, Emp::getGender, param.getGender())
                .between(param.getBegin() != null && param.getEnd() != null, Emp::getEntryDate, param.getBegin(), param.getEnd())
                .page(page);

        //获取员工集合
        List<Emp> emps = page.getRecords();

        //获取所有员工的部门id
        List<Long> deptIds = emps.stream().map(emp -> emp.getDeptId()).collect(Collectors.toList());

        //判断deptIds是否为空，不为空才去查询部门名称
        if(!deptIds.isEmpty()){

            //调用service层方法，根据员工的部门Id集合批量查询，以获取对应的部门名称的集合（只查一次部门表）
            List<Dept> depts = deptService.listByIds(deptIds);

            //在内存中将部门名称封装到员工对象中
            emps.forEach(emp -> {

                //遍历部门部门集合，获取到当前员工的部门名称
                depts.forEach(dept -> {
                    if (emp.getDeptId() != null && emp.getDeptId().equals(dept.getId())) {
                        emp.setDeptName(dept.getName());
                    }
                });
            });

        }

        //返回分页查询的数据
        return new PageResult<>(page.getTotal(), emps);

    }

    /**
     * 新增员工
     * @param emp   员工信息
     */
    @Override

    //开启线程事务，添加员工分为两部分，一个是添加员工基本信息，另一个是添加员工经历信息，要确保这两部分同时添加成功
    @Transactional(rollbackFor = Exception.class)
    public void saveEmp(Emp emp) {

        // 调用service层方法保存员工信息
        //Mybatis-Plus,只提供基础方法，创建日期和修改日期需要自己手动添加
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());

        //保存员工基本信息，this.可以省略不写
        save(emp);

        //保存员工的工作经历
        List<EmpExpr> exprList = emp.getExprList();

        //判断员工的工作经历是否为空
        if(exprList != null && exprList.size() > 0){

            //不为空，添加工作经历所属员工
            exprList.forEach(expr ->expr.setEmpId(emp.getId()));
            empExprService.saveBatch(exprList);

        }


    }

    /**
     * 根据Id查询员工信息（回显）
     *
     * @param id
     * @return
     */
    @Override
    public Emp getEmpById(Integer id) {

        //先查询基本信息
        Emp emp = getById(id);

       /* //查询工作经历
        LambdaQueryWrapper<EmpExpr> queryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<EmpExpr> eq = queryWrapper.eq(EmpExpr::getEmpId, id);
        List<EmpExpr> exprs = empExprService.list(eq);
        emp.setExprList(exprs);*/

        List<EmpExpr> empExprList = empExprService.list(new LambdaQueryWrapper<EmpExpr>()
                .eq(EmpExpr::getEmpId, id));

        //判断是否为空
        if(!empExprList.isEmpty()){

            //不为空，给emp赋值
            emp.setExprList(empExprList);
        }

        return emp;
    }


    /**
     * 修改员工信息
     *
     * @param emp
     */
    @Override

    //同时操作多表时，且其相互有影响，需要开启事务
    @Transactional(rollbackFor = Exception.class)
    public void updateEmp(Emp emp) {

        //记录修改的时间
        emp.setUpdateTime(LocalDateTime.now());

        //根据Id修改员工基本信息
        updateById(emp);

        //根据Id删除员工原始的工作经历表
        empExprService.remove(new LambdaQueryWrapper<EmpExpr>()
                .eq(EmpExpr::getEmpId, emp.getId()));

        //获取新的工作经历表
        List<EmpExpr> exprList = emp.getExprList();

        //判断新传来的工作经历集合是否为空或者长度为0，如果不为空或0，才执行添加
        if(exprList != null && !exprList.isEmpty()){

            //遍历集合
            exprList.forEach(expr ->expr.setEmpId(emp.getId()));

            //批量保存
            empExprService.saveBatch(exprList);
        }

    }


    /**
     * 批量删除
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(List<Integer> ids) {

        //先删除员工的基本信息
        removeBatchByIds(ids);

        //再删除员工的工作经历
        empExprService.remove(new LambdaQueryWrapper<EmpExpr>().in(EmpExpr::getId, ids));

    }
}
